package main;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

import windows.*;

import base.Window;

public class Telecommando implements MouseListener, MouseMotionListener, KeyListener {

	private static JFrame myFrame;
	private BufferStrategy strategy = null;
	private static Window myWindow = null;
	private Menu myMenu = null;
	public static final int width = 210;
	public static final int height = 325;
	private int transX = width - Window.width;
	private int transY = height - Window.height;
	private int rotate = 0;
	private float scaleX = 1.0f;
	private float scaleY = 1.0f;
	private boolean fullScreen = false;
	public Telecommando( )
	{
		myFrame = new JFrame( "Telecommando" );
		myFrame.setUndecorated( true );
		myFrame.setSize( new Dimension( (int)( width * scaleX ) , (int)( height * scaleY ) ) );

		Toolkit kit = myFrame.getToolkit( );
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice[] gs = ge.getScreenDevices();
		Insets in = kit.getScreenInsets(gs[0].getDefaultConfiguration());

		Dimension d = kit.getScreenSize();
		int max_width = (d.width - in.left - in.right);
		int max_height = (d.height - in.top - in.bottom);
		myFrame.setLocation( (int) ( max_width - myFrame.getWidth( ) ) >> 1 , ( int ) ( max_height - myFrame.getHeight( ) ) >> 1 );
		myFrame.setVisible( true );

		myFrame.createBufferStrategy( 2 );
		strategy = myFrame.getBufferStrategy( );

		myFrame.addMouseListener( this );
		myFrame.addMouseMotionListener( this );

		makeRooms( );
		makeWindows( );
		myWindow = null;
		myMenu = new Menu( );
		myFrame.addKeyListener( this );

		new VirtualRoom( );
		myFrame.setAlwaysOnTop( true );
		myFrame.setAlwaysOnTop( false );
		run( );
	}

	public void makeWindows( )
	{
		new TestWindow( );
	}

	public static void setWindow( Window wind )
	{
		myWindow = wind;
	}

	private void makeRooms( )
	{
		ImageLibrary.addSet( "r" , "Images/r.png" , 5 , 2 );
		ImageLibrary.addSet( "room" , "Images/rooms.png" , 4 , 4 );
		ImageLibrary.addSet( "fav" , "Images/Favorite.png" , 2 , 1 );
		RoomLibrary.add( "Favorites" ,  "room[0]" );
		RoomLibrary.add( "Living Room" ,  "room[6]" );
		RoomLibrary.add( "Kitchen" ,  "room[7]" );
		RoomLibrary.add( "Office" ,  "room[8]" );
		RoomLibrary.add( "Dining Room" ,  "room[2]" );
		RoomLibrary.add( "Bedroom" ,  "room[3]" );
		RoomLibrary.add( "Bedroom" ,  "room[3]" );
		RoomLibrary.add( "Bedroom" ,  "room[3]" );
		RoomLibrary.add( "Bathroom" ,  "room[4]" );
		RoomLibrary.add( "Bathroom" ,  "room[4]" );
		RoomLibrary.add( "Garage" ,  "room[5]" );
		RoomLibrary.add( "Uncategorized" ,  "room[1]" );
	}

	public static JFrame getInstance( )
	{
		return myFrame;
	}

	private String imageBackground = "Images/backgroundDown.png";
	private String imageForeground = "Images/backgroundUp.png";
	public void run( )
	{
		
		ImageLibrary.add( imageBackground , imageBackground );
		ImageLibrary.add( imageForeground , imageForeground );
		for( ; ; )
		{
			if( myMenu != null )
				myMenu.update( );
			if( myWindow != null )
				myWindow.update( );
			draw( strategy.getDrawGraphics( ) );
			strategy.show( );
			try{ Thread.sleep( 3 ); }catch( Exception e ){ };
		}
	}

	public void mouseClicked( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseClicked( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseClicked( arg0 );
		myMenu.resetLocation( );
	}
	public void mousePressed( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mousePressed( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mousePressed( arg0 );
		myMenu.resetLocation( );
	}
	public void mouseReleased( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseReleased( arg0 ) );
			//return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseReleased( arg0 );
	}
	public void mouseEntered( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseEntered( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseEntered( arg0 );
	}
	public void mouseExited( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseExited( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseExited( arg0 );
	}
	public void mouseDragged( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseDragged( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseDragged( arg0 );
	}
	public void mouseMoved( MouseEvent arg0 )
	{
		arg0 = translateCords( arg0 );
		if( myMenu != null && myMenu.mouseMoved( arg0 ) )
			return;
		arg0.translatePoint( -transX , -transY );
		if( myWindow != null )
			myWindow.mouseMoved( arg0 );
	}

	private MouseEvent translateCords( MouseEvent arg0 )
	{
		//(Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger, int button) 
		int x = arg0.getX();
		int y = arg0.getY();
		if( scaleX == 0 )
			scaleX = 0.01f;
		if( scaleY == 0 )
			scaleY = 0.01f;
		if( rotate == 90 )
		{
			y = height - (int)( arg0.getX( ) / scaleY );
			x = (int)( arg0.getY( ) / scaleX );
		}
		else if( rotate == 180 )
		{
			y = height - (int)( arg0.getY( ) / scaleY );
			x = width - (int)( arg0.getX( ) / scaleX );
		}
		else if( rotate == 270 )
		{
			y = (int)( arg0.getX( ) / scaleY );
			x = width - (int)( arg0.getY( ) / scaleX );
		}
		else
		{
			x = (int)( x / scaleX );
			y = (int)( y / scaleY );
		}

		return new MouseEvent( (Component)arg0.getSource() , arg0.getID() , arg0.getWhen() , arg0.getModifiers() , x , y , arg0.getClickCount() , arg0.isPopupTrigger() , arg0.getButton() );
	}

	public static final Font normFont = new Font( "norm" , Font.PLAIN , 13 );
	public void draw( Graphics g )
	{
		Graphics2D g2d = (Graphics2D)g;

		double rotate = 0;
		if( this.rotate == 90 )
			rotate = Math.PI/2;
		else if( this.rotate == 180 )
			rotate = Math.PI;
		else if( this.rotate == 270 )
			rotate = Math.PI*3/2;

		if( this.rotate == 90 || this.rotate == 270 )
		{
			g2d.rotate( rotate , 0 , 0 );
			if( scaleX != 1.0f || scaleY != 1.0f )
				g2d.scale( scaleX , scaleY );
			if( this.rotate == 270 )
				g2d.translate( -width , 0 );
			if( this.rotate == 90 )
				g2d.translate( 0 , -height );
		}
		else if( this.rotate == 180 )
		{
			g2d.rotate( rotate , 0 , 0 );
			if( scaleX != 1.0f || scaleY != 1.0f )
				g2d.scale( scaleX , scaleY );
			g2d.translate( -width , -height );
		}
		else if( scaleX != 1.0f || scaleY != 1.0f )
			g2d.scale( scaleX , scaleY );

		g2d.setColor( Color.black );
		g2d.drawImage( ImageLibrary.get( imageBackground ) , 0 , 0 , myFrame );

		if( myWindow != null )
		{
			g2d.translate( transX , transY );
			myWindow.draw( g2d );
			g2d.translate( -transX , -transY );
		}
		g2d.setFont( normFont );

		g2d.setColor( Color.yellow );
		if( myWindow != null )
			g2d.drawString( myWindow.getName( ) , 1 + transX , 12 );
		g2d.setClip( myMenu.getClip( ) );
		myMenu.draw( g2d );
		g2d.setClip( 0 , 0 , width , height );
		g2d.drawImage( ImageLibrary.get( imageForeground ) , 0 , 0 , myFrame );
	}

	public static void main( String args[] )
	{
		new Telecommando( );
	}

	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	private int lastRotate = 0;
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		if( e.getKeyCode() == KeyEvent.VK_ESCAPE )
			System.exit( 0 );
		else if( e.getKeyCode( ) == KeyEvent.VK_RIGHT )
		{
			rotate += 90;
			if( rotate == 360 )
				rotate = 0;
		}
		else if( e.getKeyCode( ) == KeyEvent.VK_LEFT )
		{
			rotate -= 90;
			if( rotate == -90 )
				rotate = 270;
		}
		else if( e.getKeyCode( ) == KeyEvent.VK_F )
		{
			fullScreen = !fullScreen;
			if( !fullScreen )
			{
				if( rotate == 0 || rotate == 180 )
					myFrame.setSize( new Dimension( width , height ) );
				else
					myFrame.setSize( new Dimension( height , width ) );
				lastRotate = rotate;
				scaleX = 1.0f;
				scaleY = 1.0f;
			}
		}
		else if( e.getKeyCode( ) == KeyEvent.VK_2 )
		{
			if( scaleX == 2.0f && scaleY == 2.0f )
			{
				scaleX = 1.0f;
				scaleY = 1.0f;
			}
			else
			{
				scaleX = 2.0f;
				scaleY = 2.0f;
			}
			fullScreen = false;
			if( !fullScreen )
			{
				if( rotate == 0 || rotate == 180 )
					myFrame.setSize( new Dimension( (int)(width * scaleX) , (int)(height * scaleX) ) );
				else
					myFrame.setSize( new Dimension( (int)(height * scaleY) , (int)(width * scaleY) ) );
				lastRotate = rotate;
			}
		}
		Toolkit kit = myFrame.getToolkit( );
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice[] gs = ge.getScreenDevices();
		Insets in = kit.getScreenInsets(gs[0].getDefaultConfiguration());
		Dimension d = kit.getScreenSize();
		int max_width = (d.width - in.left - in.right);
		int max_height = (d.height - in.top - in.bottom);
		if( !fullScreen )
		{
			if( rotate != lastRotate )
			{
				myFrame.setSize( new Dimension( myFrame.getHeight( ) , myFrame.getWidth( ) ) );
				lastRotate = rotate;
			}
			myFrame.setLocation( (int) ( max_width - myFrame.getWidth( ) ) >> 1 , ( int ) ( max_height - myFrame.getHeight( ) ) >> 1 );
		}
		else
		{
			scaleX = (float)max_width/(float)width;
			scaleY = (float)max_height/(float)height;

			myFrame.setSize( new Dimension( (int)( width * scaleX ) , (int)( height*scaleY ) ) );
			if( rotate == 0 || rotate == 180 )
			{
				scaleX = (float)max_width/(float)width;
				scaleY = (float)max_height/(float)height;
			}
			else
			{
				scaleX = (float)max_height/(float)width;
				scaleY = (float)max_width/(float)height;
			}
			myFrame.setLocation( 0 , 0 );
		}
	}

	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
}
